package io.elegant.sessions

import android.app.AlertDialog
import android.content.Context
import com.google.protobuf.Any
import io.elegant.*
import io.elegant.ElegantApiGrpc.ElegantApiStub
import io.grpc.stub.StreamObserver
import kotlinx.coroutines.launch

class GenericDialogSession(
    stub: ElegantApiStub,
    private val context: Context
): BaseSession(stub, context) {
    override val sendStreamObserver: StreamObserver<Elegant.Interaction> = stub.genericDialog(receiveStreamObserver)
    private var dialog: AlertDialog? = null
    override fun onCreate(sessionId: Long, futureId: Long, vararg argv: Any) {
        dialog = AlertDialog
            .Builder(context)
            .setTitle(argv[0].toStringValue())
            .setMessage(argv[1].toStringValue())
            .setPositiveButton(argv[2].toStringValueOrNull(), null)
            .setNegativeButton(argv[3].toStringValueOrNull(), null)
            .create()
            .also {
                it.show()
            }
        super.onCreate(sessionId, futureId, *argv)
    }
    override fun onDestroy() {
        dialog?.dismiss()
        dialog = null
        super.onDestroy()
    }
    override suspend fun onReceive(name: String, sessionId: Long, futureId: Long, vararg argv: Any) {
        when (name) {
            "setOnCancelListener" -> setOnCancelListener(*argv)
            "setMessage" -> setMessage(*argv)
            "setTitle" -> setTitle(*argv)
            "setOkButtonText" -> setOkButtonText(*argv)
            "setCancelButtonText" -> setCancelButtonText(*argv)
            "setOnOkButtonClickListener" -> setOnOkButtonClickListener(*argv)
            "setOnCancelButtonClickListener" -> setOnCancelButtonClickListener(*argv)
            else -> super.onReceive(name, sessionId, futureId, *argv)
        }
    }
    private fun setOnCancelListener(vararg argv: Any) = dialog?.setOnCancelListener {
        csMain.launch {
            argv[0].sendCallback()
        }
    }
    private fun setMessage(vararg argv: Any) = dialog?.let {
        if (argv.isEmpty())
            throw IllegalArgumentException("Missing param `message` from the server calling this `setMessage` method.")
        it.setMessage(argv[0].toStringValue())
    }
    private fun setTitle(vararg argv: Any) = dialog?.let {
        if (argv.isEmpty())
            throw IllegalArgumentException("Missing param `title` from the server calling this `setTitle` method.")
        it.setTitle(argv[0].toStringValue())
    }
    private fun setOkButtonText(vararg argv: Any) = dialog?.let {
        if (argv.isEmpty())
            throw IllegalArgumentException("Missing param `text` from the server calling this `setOkButtonText` method.")
        it.getButton(AlertDialog.BUTTON_POSITIVE).text = argv[0].toStringValue()
    }
    private fun setCancelButtonText(vararg argv: Any) = dialog?.let {
        if (argv.isEmpty())
            throw IllegalArgumentException("Missing param `text` from the server calling this `setCancelButtonText` method.")
        it.getButton(AlertDialog.BUTTON_NEGATIVE).text = argv[0].toStringValue()
    }
    private fun setOnOkButtonClickListener(vararg argv: Any) = dialog?.let {
        if (argv.isEmpty())
            throw IllegalArgumentException("Missing param `onClickListener` from the server calling this `setOnOkButtonClickListener` method.")
        it.setButton(AlertDialog.BUTTON_POSITIVE, null) { _, _ ->
            csMain.launch {
                argv[0].sendCallback()
            }
        }
    }
    private fun setOnCancelButtonClickListener(vararg argv: Any) = dialog?.let {
        if (argv.isEmpty())
            throw IllegalArgumentException("Missing param `onClickListener` from the server calling this `setOnCancelButtonClickListener` method.")
        it.setButton(AlertDialog.BUTTON_NEGATIVE, null) { _, _ ->
            csMain.launch {
                argv[0].sendCallback()
            }
        }
    }
}